<template>
  <a-modal
    v-model:open="open"
    :title="'新增版本'"
    centered
    :after-close="reset"
    :width="600"
    :ok-text="'创建 '"
    :confirm-loading="confirmLoading"
    @ok="onOk"
  >
    <a-form ref="formRef" :model="formState" :rules="rules" layout="vertical">
      <a-form-item>
        <template #label>版本号<span class="required-star">*</span></template>
        <div class="flex gap-12">
          <div class="flex-1">
            <a-form-item name="versionName" :style="{ marginRight: '12px', flex: 1 }">
              <a-select
                v-model:value="formState.versionName"
                placeholder="请选择版本号"
                :field-names="{ label: 'version', value: 'id' }"
                :options="versionOption"
                :get-popup-container="(triggerNode: any) => triggerNode.parentNode"
              />
            </a-form-item>
          </div>
          <div class="flex-1">
            <a-form-item
              v-if="formState.versionName === 'add-version'"
              name="versionInput"
              :rules="[
                { required: true, message: '请输入版本号名称', trigger: 'change' },
                {
                  pattern: /^(?!\.)(\d+\.)*\d+$/,
                  message: '仅支持数字和小数点,且以数字结尾'
                }
              ]"
            >
              <a-input v-model:value="formState.versionInput" v-trim :maxlength="10" placeholder="例如：1.0.1" />
            </a-form-item>
          </div>
        </div>
      </a-form-item>
      <a-form-item label="镜像" name="imageId">
        <a-select
          v-model:value="formState.imageId"
          :options="imageList"
          placeholder="请选择镜像"
          :field-names="{ label: 'imageName', value: 'id' }"
          class="w-440"
          @change="imageSelect"
        />
      </a-form-item>
      <a-form-item label="框架" name="frame">
        <g-input v-trim :value="formState.frame" :search="false" placeholder="请选择框架" disabled />
      </a-form-item>
      <a-form-item label="镜像文件" name="url">
        <file-upload
          v-model:file-url="formState.url"
          class="file-upload w-440"
          :max-count="1"
          :is-preview="false"
          accept="zip"
          suffix="zip"
          :module-custom-prefix="prefixUrl"
          :custom-prefix-name-has-unix="true"
          :max-file-size="200"
          @upload-success-after="fileUploadSuccess"
        >
          <a-button type="dashed" size="small" class="icon-with-btn btn-mini">
            <i class="iconfont icon-upload-line"></i>
            上传
          </a-button>
        </file-upload>
      </a-form-item>
      <a-form-item label="描述" name="description">
        <a-textarea v-model:value="formState.description" v-trim class="h-76" placeholder="请输入描述" :maxlength="200" show-count />
      </a-form-item>
    </a-form>
  </a-modal>
</template>

<script lang="ts" setup>
  import { type FormInstance, message } from 'ant-design-vue'
  import type { Rule } from 'ant-design-vue/es/form'
  import { cloneDeep } from 'g6-fn'
  import { ref } from 'vue'
  import { useRequest } from 'vue-request'

  import { mirrorManageApi, modelLibraryApi } from '@/services/api'

  interface VersionOption {
    id: string
    version: string
  }

  export interface Props {
    afterCloseFn?: () => void
  }

  const props = withDefaults(defineProps<Props>(), {
    afterCloseFn: () => {}
  })

  const formRef = ref<FormInstance>()
  interface FormState {
    modelBaseId: string
    version: string
    versionName: string | undefined
    description: string
    imageId: string | undefined
    url: string
    size: number | string
    [key: string]: any
  }
  const open = ref(false)
  const prefixUrl = ref('/')
  const formState = ref<FormState>({
    modelBaseId: '',
    version: '',
    versionName: undefined,
    description: '',
    imageId: undefined,
    url: '',
    size: ''
  })

  const rules: Record<string, Rule[]> = {
    versionName: [{ required: true, message: '请选择版本号', trigger: 'change' }],
    imageId: [{ required: true, trigger: 'change', message: '请选择镜像' }],
    frame: [{ required: true, trigger: 'change', message: '请输入框架' }],
    url: [{ required: true, trigger: 'change', message: '请上传镜像文件' }]
  }

  const imageSelect = (val: any) => {
    formState.value.frame = imageList.value.find((item: any) => item.id === val)?.frame
    formRef.value?.validate('frame')
  }

  const reset = () => {
    formRef.value?.resetFields()
    formState.value = {
      modelBaseId: '',
      version: '',
      versionName: undefined,
      description: '',
      imageId: undefined,
      url: '',
      size: ''
    }
  }

  const confirmLoading = ref(false)
  const onOk = async () => {
    await formRef.value?.validateFields()
    let params = cloneDeep(formState.value)
    if (formState.value.versionName === 'add-version') {
      params.version = formState.value.versionInput
    } else {
      params.version = formState.value.versionName
    }
    confirmLoading.value = true
    try {
      await modelLibraryApi.addModalVersion(params, { isAddUid: true })
      confirmLoading.value = false
      open.value = false
      message.success('操作成功')
      props.afterCloseFn()
    } catch (error) {
      confirmLoading.value = false
    }
  }

  const fileUploadSuccess = (file: any) => {
    formState.value.size = file.size
  }

  //已有版本号
  const versionOption = ref<VersionOption[]>([])
  const queryVersionNumber = async (): Promise<void> => {
    const res = await modelLibraryApi.existingVersionNumber({ modelBaseId: formState.value.modelBaseId })
    versionOption.value = res.data
      .map((item: VersionOption) => {
        return { id: item, version: item }
      })
      .concat([{ id: 'add-version', version: '新增版本' }])
  }

  // 获取镜像数据
  const imageList = ref()
  const { runAsync: runGetImageList } = useRequest(mirrorManageApi.imageCommon, {
    onSuccess: (data: any) => {
      imageList.value = data.data
    }
  })
  runGetImageList({ dockerPurposeType: 1 })
  defineExpose({
    open: (modalId: any, url: string) => {
      formState.value.modelBaseId = modalId
      if (url) {
        prefixUrl.value = url
      }
      queryVersionNumber()
      open.value = true
    }
  })
</script>
<style lang="less" scoped>
  .required-star {
    display: inline-block !important;
    font-size: 14px;
    font-family: SimSun, sans-serif;
    color: rgba(25, 25, 48, 0.75);
    font-weight: 700;
    line-height: 1;
    margin-inline: 2px 8px;
    transform: translateY(-1px);
  }
</style>
